#region License Revision: 0 Last Revised: 6/18/2008 11:00 AM
/******************************************************************************
Copyright (c) Microsoft Corporation.  All rights reserved.


This file is licensed under the Microsoft Public License (Ms-PL). A copy of the Ms-PL should accompany this file. 
If it does not, you can obtain a copy from: 

http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
******************************************************************************/
#endregion // License
using System;
using System.Windows.Browser;
using System.Diagnostics;
using ScriptInterop;

namespace VIEWS // Virtual Earth Wrapper
{

public class VEShapeLayer : JSObject 
{
	/// <summary>String holding JavaScript class name</summary>
	private static string thisClass = "VEShapeLayer";
	
	/// <summary>Get the JavaScript class name</summary>
	/// <returns type="String">The class name used in JavaScript </returns>		
	public override string ClassName
	{
		get { return thisClass; }
	}

	/// <summary>Construct a C# wrapper from a ScriptObject</summary>
	/// <param name="so">A ScriptObjet from JScript.</param>
	public VEShapeLayer(ScriptObject so) : base(so) { }

	/// <summary>Initializes a new instance of the VEShapeLayer class.</summary>
	public VEShapeLayer()
	{
		ScriptObject = CreateClass();
	}

	/// <summary>Adds a VEShape Class object to the layer.</summary>
	/// <param name="shape" type="VEShape">The VEShape object to be added. Required.</param>
	public void AddShape(VEShape shape)
	{
		Invoke("AddShape", (ScriptObject)shape);
	}

	/// <summary>Adds an array of VEShape objects to the layer.</summary>
	/// <param name="shapes" type="VEShape">An array of VEShape objects to be added. Required.</param>
	public void AddShape(VEShape[] shapes)
	{
		JSArray<ScriptObject> arrShape = ConvertToScriptObjectJSArray(shapes);
		Invoke("AddShape", (ScriptObject)arrShape);
		
	}

	/// <summary>Deletes all VEShape Class objects (pushpins, polylines, and polygons) from the layer.</summary>
	public void DeleteAllShapes()
	{
		Invoke("DeleteAllShapes");
	}

	/// <summary>Deletes a VEShape Class object from the layer.</summary>
	/// <param name="shape" type="VEShape">A reference to the VEShape object (pushpin, polyline, and polygon) to delete. Required.</param>
	public void DeleteShape(VEShape shape)
	{
		Invoke("DeleteShape", (ScriptObject)shape);
	}
	
	/// <summary>A best-fit VELatLongRectangle Class object based on the shapes currently present in the layer.</summary>
	public VELatLongRectangle BoundingRectangle
	{
		get
        {
            ScriptObject so = Invoke<ScriptObject>("GetBoundingRectangle");
            VELatLongRectangle rect = new VELatLongRectangle(so);
            return rect;
        }
	}

    /// <summary>
    /// Returns an array of <see cref="VEClusterSpecification"/> objects representing the calculated pushpin clusters.
    /// </summary>
    /// <param name="type">
    /// A <see cref="VEClusteringType"/> enumeration specifying the algorithm used to determine which pushpins to cluster.
    /// </param>
    /// <returns>
    /// An array of <see cref="VEClusterSpecification"/> objects representing the calculated pushpin clusters.
    /// </returns>
    public VEClusterSpecification[] GetClusteredShapes(VEClusteringType type)
    {
        ScriptObject so = Invoke<ScriptObject>("GetClusteredShapes", ScriptEnumConverter.ToString(type));
        return ConvertToArray<VEClusterSpecification>(so);
    }

	/// <summary>Retrieves a reference to a VEShape Class object contained in this layer based on the specified ID.</summary>
	/// <param name="id" type="String">The identifier of the VEShape object. Required.</param>
	/// <returns type="VEShape"></returns>
	public VEShape GetShapeById(string id)
	{
		ScriptObject so = Invoke<ScriptObject>("GetShapeByID", id);
		VEShape shape = VEShape.GetShapeObject(so);
		return shape;
	}

	/// <summary>Retrieves a reference to a VEShape Class object contained in this layer based on the specified index.</summary>
	/// <param name="index" type="Number">The index of the shape to retrieve. Required.</param>
	/// <returns type="VEShape"></returns>
	public VEShape GetShapeByIndex(int index)
	{
		ScriptObject so = Invoke<ScriptObject>("GetShapeByIndex", index);
		VEShape shape = VEShape.GetShapeObject(so);
		return shape;
	}

    /// <summary>
    /// Sets the method for determining which pushpins are clustered as well as how the cluster is displayed.
    /// </summary>
    /// <param name="type">
    /// A <see cref="VEClusteringType"/> enumeration specifying which shapes to cluster.
    /// </param>
    /// <param name="options">
    /// A <see cref="VEClusteringOptions"/> object specifying how the pushpin cluster is displayed. This parameter may 
    /// be <see langword="null"/>.
    /// </param>
    public void SetClusteringConfiguration(VEClusteringType type, VEClusteringOptions options)
    {
        string stype = ScriptEnumConverter.ToString(type);
        if (options != null)
        {
            Invoke("SetClusteringConfiguration", stype, options);
        }
        else
        {
            Invoke("SetClusteringConfiguration", stype);
        }
    }

	/// <summary>The total number of shapes in the current layer.</summary>
	public int ShapeCount
	{
		get
        {
            double dbl = Invoke<double>("GetShapeCount");
            return (int)dbl;
        }
	}

	// Properties to simiplify programming

	/// <summary>The description of the VEShapeLayer object.</summary>
	public string Description
	{
        get { return Invoke<string>("GetDescription"); }
        set { Invoke("SetDescription", value); }
	}

	/// <summary>The title of the VEShapeLayer object.</summary>
	public string Title
	{
        get { return Invoke<string>("GetTitle"); }
        set { Invoke("SetTitle", value); }
	}

	/// <summary>Visibility property for layer on the map.</summary>
	public bool Visible
	{
        get { return Invoke<bool>("IsVisible"); }
		set
        {
            if (value)
            {
                Invoke("Show");
            }
            else
            {
                Invoke("Hide");
            }
        }
	}
}

}
